#import scanf
import parse
import fire
import time
import datetime
import os
import random
import regex as re
from math import sin

# 输出log，便于调试
import logging


def update_data_dict_gen(t=None,mode='sin',selected_cols=None,data_types=None):
    """假造一些数据，返回字典格式
    """
    now_ts = time.time() if t is None else t # 默认当前时间
    update_data_dict = {}
    
    # 时间处理
    now_datetime = datetime.datetime.fromtimestamp(now_ts)
    update_data_dict['yyyy'] = now_datetime.year
    update_data_dict['MM'] = now_datetime.month
    update_data_dict['dd'] = now_datetime.day
    update_data_dict['hh'] = now_datetime.hour
    update_data_dict['mm'] = now_datetime.minute
    update_data_dict['ss'] = now_datetime.second


    # 生成数据
    if mode == 'sin':
        # 正弦变化的数据
        period = 100 # s
        shift = 10 # s
        for i,col in enumerate(selected_cols):
            if data_types[col] == 'f':
                update_data_dict[col] = 1000*(2+sin((now_ts+shift*i)/period))
            elif data_types[col] == 'd':
                update_data_dict[col] = int(1000*(1+sin((now_ts+shift*i)/period)))
            else :
                raise RuntimeError(f'unknown data type {col}:{data_types[col]}')
    elif mode == 'random':
        # 随机数据
        max = 1.0
        min = 0.0
        for i,col in enumerate(selected_cols):
            update_data_dict[col] = random.random()*(max-min)+min
    else:
        raise RuntimeError(f'mode={mode}, it must be "sin" or "random"')
    return update_data_dict

def main(output_filename= None,
        delay_time = 0.95,
        test_mode=False,
        max_time_hours = 24,
        mode='sin',
        log_level = 'INFO'):
    """假造一些输出到log文件，模拟实际设备
    """
    # 初始化
    logging.basicConfig(level = getattr(logging,log_level.upper(),logging.INFO)) # 默认info
    file_base_name = os.path.basename(__file__)
    logger = logging.getLogger(file_base_name)

    # header
    before_header="""AETHALOMETER
Serial number = AE33-S04-00358
Application version = 1.4.2.0
Number of channels = 7

"""
    # 分隔符
    sep = ' '
    col_name_sep = ';'
    # 列名
    header = 'Date(yyyy/MM/dd); Time(hh:mm:ss); Timebase; RefCh1; Sen1Ch1; Sen2Ch1; RefCh2; Sen1Ch2; Sen2Ch2; RefCh3; Sen1Ch3; Sen2Ch3; RefCh4; Sen1Ch4; Sen2Ch4; RefCh5; Sen1Ch5; Sen2Ch5; RefCh6; Sen1Ch6; Sen2Ch6; RefCh7; Sen1Ch7; Sen2Ch7; Flow1; Flow2; FlowC; Pressure(Pa); Temperature(°C); BB(%); ContTemp; SupplyTemp; Status; ContStatus; DetectStatus; LedStatus; ValveStatus; LedTemp; BC11; BC12; BC1; BC21; BC22; BC2; BC31; BC32; BC3; BC41; BC42; BC4; BC51; BC52; BC5; BC61; BC62; BC6; BC71; BC72; BC7; K1; K2; K3; K4; K5; K6; K7; TapeAdvCount;'
    display_names = [n.strip() for n in header.split(col_name_sep)[:-1]]
    col_names = header.split(col_name_sep)
    # re.sub('[^a-zA-Z0-9]','_',n.strip())
    # 把'Temperature(°C)'转化为'Temperature__C_'
    ## 注意，原始数据只有67列，但是下面的数据有70列！！
    col_names = 'yyyy,MM,dd,hh,mm,ss'.split(',')+ [re.sub('[^a-zA-Z0-9]','_',n.strip())  for n in col_names[2:-1]] + ['Unknown1','Unknown2','Unknown3']
    # 格式
    # example 
    # 2018/11/27 08:36:18 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3461 1548 0 101325 20 0.0 5 10 1 0 20 10 00000 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.007738049 0.007743395 0.008087777 0.00822126 0.009227347 0.007967672 0.009248562 1326 5 0 0
    # datetime = 2018/11/27 08:36:18
    data_write_formats = '04d,02d,02d,02d,02d,02d'.split(',')+['d']*27+['f']+['d']*29+['f']*7+['d']*4
    data_read_formats = [format[-1] for format in data_write_formats]

    # data types
    data_types = dict(zip(col_names, data_read_formats))

    # selected cols
    selected_cols = [col.strip() for col in 'BC6'.split(',') ]
    
    # 默认值，为保持完整性
    defaults_str = '2018/11/27 12:10:28 1 850506 803293 958959 987875 646232 721277 945804 650772 714832 819977 617467 675464 913549 766363 823828 749052 915690 978777 785257 921569 972926 2006 985 2991 101325 20 0.0 26 41 0 0 10 10 00000 26 1258 1645 1433 1284 1668 1361 356 635 374 1213 1384 1263 96 -823 100 -335 -682 -341 -81 1351 -83 0.007738049 0.007743395 0.008087777 0.00822126 0.009227347 0.007967672 0.009248562 1327 5 0 0'
    # 第一行
    logger.info(header)

    # 生成格式化字符串
    datetime_formatter = '{yyyy:04d}/{MM:02d}/{dd:02d} {hh:02d}:{mm:02d}:{ss:02d}'
    line_write_formatter=datetime_formatter +sep + sep.join([f'{{{col_name}:{format}}}' for col_name,format in zip(col_names[6:],data_write_formats[6:])])
    logger.info(line_write_formatter)

    datetime_formatter = '{yyyy:d}/{MM:d}/{dd:d} {hh:d}:{mm:d}:{ss:d}'
    line_read_formatter=datetime_formatter +sep + sep.join([f'{{{col_name}:{format}}}' for col_name,format in zip(col_names[6:],data_read_formats[6:])])
    logger.info(line_read_formatter)

    # 简单测试
    parse_result = parse.parse(line_read_formatter,defaults_str)
    logger.info(parse_result)
    if parse_result is None:
        raise RuntimeError('Something go wrong!')

    # 默认值
    data_dict_defaults = parse_result.named

    # example data
    # raw_data_example_filename = r"raw_data\课题3\AE33\AE33-S04-00358_20181127.dat"
    
    # 输出文件名
    output_filename = output_filename if output_filename is not None else (file_base_name+r".test.log")
    with open(output_filename,'w+',encoding='utf-8') as OF:
        if test_mode: OF = None
        # before header
        print(before_header,file=OF)
        #header
        print(header,file=OF)
        # after header, before data, two empty lines
        print('',file=OF,flush=True)
        print('',file=OF,flush=True)
        #data lines
        start_time = time.time()
        while(time.time()<start_time + max_time_hours*24*3600): # max hours
            data_dict = data_dict_defaults
            update_data_dict = update_data_dict_gen(mode=mode,selected_cols=selected_cols,data_types=data_types)
            logger.info(update_data_dict)
            data_dict.update(update_data_dict)
            line = line_write_formatter.format(**data_dict)
            print(line,file=OF,flush=True)# flush is necessary
            time.sleep(delay_time)

if __name__ == "__main__":
    fire.Fire(main) # 利用fire命令行化
